package visualization;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.List;

import neuron.Coord;
import neuron.Dendrite;
import neuron.Neuron;
import neuron.Statistics;

public class JNeuroCoordScatter extends JScatterPlot {

	Neuron n = null;
	int axis = 0;
	
	public JNeuroCoordScatter(Neuron n, int axis) {
		super();
		this.n = n;
		this.axis = axis;
		xlabel = "X";
		ylabel = (axis==0?"Y":"Z");
		title = "Basal coordinates";
		minx = -200; maxx = 200; miny = -200; maxy = 200;
		setSize(600, 500);
		render();
		repaint();
	}
	
	@Override
	public double[][] getData() {
		if (n == null) return new double[0][0];
		
		List<Coord> lst = n.getAllBasalCoordinates();
		double[][] data = new double[lst.size()][];
		for (int i = 0; i < lst.size(); i++) {
			double x = lst.get(i).x;
			double y = lst.get(i).y;
			double z = lst.get(i).z;
			
			data[i] = new double[]{ x, (axis == 0? y:z)};
		}
		return data;
	}
	
	public void paintOverlay(Graphics2D g) 
	{
		if (n == null) return;
		
		if (axis == 0) return;
		
		List<Coord> lst = n.getAllBasalCoordinates();
	
		// compute mean
		double xsum=0, zsum=0;
		for (Coord c : lst) { xsum += c.x; zsum += c.z; }
		double xmean = xsum / lst.size(), zmean = zsum / lst.size();
		
		// std dev
		double xdevsum = 0, zdevsum = 0;
		for (Coord c : lst) { xdevsum += Math.pow(c.x-xmean,2); zdevsum += Math.pow(c.z-zmean,2); }
		double xstd = Math.sqrt(xdevsum/lst.size());
		double zstd = Math.sqrt(zdevsum/lst.size());
		
		// std dev vector
		double vecLen = Math.sqrt(xstd*xstd+zstd*zstd);
		double ux = xstd / vecLen, uy = zstd / vecLen;

		// STD DEV LINE
		g.setColor(Color.black);
		g.drawLine((int)(cx-ux*200), (int)(cy+uy*200), (int)(cx+ux*200), (int)(cy-uy*200));

		// -30um LINE
		g.setColor(Color.red);
		g.drawLine((int)(cx-ux*200), (int)(cy+uy*200-30*yscale), (int)(cx+ux*200), (int)(cy-uy*200-30*yscale));

		// +90um LINE
		g.setColor(Color.magenta);
		g.drawLine((int)(cx-ux*200), (int)(cy+uy*200+90*yscale), (int)(cx+ux*200), (int)(cy-uy*200+90*yscale));
		
		Line2D.Double devline = new Line2D.Double(-ux*1000, -uy*1000+30, ux*1000, uy*1000+30);
		for (Dendrite d : n.basalDendrites()) {
			Statistics dstat = new Statistics(d.root);
			for (Coord c : d.getEndPoints()) {
				double dist = devline.ptLineDist(c.x, c.z);
//				System.out.println("POINT " + c.x + ", " + c.z + "  distance " + dist + ", dendrite length " + dstat.totalLength() + ", #TS " + dstat.countTerminalSegments());
				System.out.format("%.2f\t%.2f\t%.2f\t%.2f\n", dist, dstat.totalLength(), 0.0+dstat.countTerminalSegments(), c.d);
//				Color clr = Color.getHSBColor((float) (dist/200.0), 1, 1);
				Color clr = Color.black;
				g.setColor(clr);
				double sx = cx + c.x*xscale;
				double sy = cy - c.z*yscale;
				int size = (int) (15 - Math.log(dist));
				if (size < 1) size = 1;
				//g.fillArc((int) sx, (int) sy, size, size, 0, 360);
				g.drawString(String.format("%.0f", dist), (int)sx, (int)sy);
			}
		}
	}
}
